package xin.nick.common.util;

import cn.hutool.http.HttpUtil;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.TextAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import xin.nick.common.entity.WordField;
import xin.nick.common.enums.WordFieldTypeEnum;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Nick
 * @since 2022/7/22/022
 */
public class WordUtil {

    private static final Pattern PATTERN_TEXT = Pattern.compile("\\$\\{\\{([^}]*)\\}\\}");
    private static final Pattern PATTERN_TABLE = Pattern.compile("#\\{\\{([^}]*)\\}\\}");
    private static final String STRING_FLAG= "$";
    private static final String TABLE_FLAG= "#";

    /**
     * 填充word模板
     * @param filePath
     * @param fieldMap
     * @return
     * @throws IOException
     * @throws InvalidFormatException
     */
    public static XWPFDocument fillWordTemplate(String filePath, Map<String, WordField> fieldMap) throws IOException, InvalidFormatException {
        //解析docx模板并获取document对象
        XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(filePath));
        return fillWordTemplate(document,fieldMap );
    }

    /**
     * 填充插入表格
     * @param filePath
     * @param fieldMap
     * @return
     * @throws IOException
     */
    public static XWPFDocument insertWordTemplate(String filePath, Map<String, WordField> fieldMap) throws IOException {
        //解析docx模板并获取document对象
        XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(filePath));
        return insertWordTemplate(document,fieldMap );
    }


    /**
     * 填充word模板
     *
     * @param document
     * @param fieldMap
     * @return
     * @throws IOException
     * @throws InvalidFormatException
     */
    public static XWPFDocument fillWordTemplate(XWPFDocument document, Map<String, WordField> fieldMap) throws IOException, InvalidFormatException {


        // 所有的段落信息
        List<XWPFParagraph> paragraphTextList = new ArrayList<>();
        List<XWPFParagraph> paragraphList = document.getParagraphs();
        List<XWPFParagraph> paragraphListFromTable = getParagraphListFromTable(document);

        // 将文章段落和表格的段落全部加在一起
        if (!CollectionUtils.isEmpty(paragraphList)) {
            paragraphTextList.addAll(paragraphList);
        }
        if (!CollectionUtils.isEmpty(paragraphListFromTable)) {
            paragraphTextList.addAll(paragraphListFromTable);
        }


        // 遍历段落,进行替换
        for (XWPFParagraph xwpfParagraph : paragraphTextList) {
            String paragraphText = xwpfParagraph.getText();
            // 段落存在标识则进行文件行扫描判断
            if (checkText(paragraphText)) {
                List<XWPFRun> runList = xwpfParagraph.getRuns();
                for (XWPFRun xwpfRun : runList) {
                    String runText = xwpfRun.toString();
                    if (checkText(runText)) {

                        // 确定行了
                        // 取出里面所有的标识位
                        List<String> fieldKeyList = getFieldKeyList(runText);
                        if (!CollectionUtils.isEmpty(fieldKeyList)) {
                            for (String fieldKey : fieldKeyList) {

                                // 从map中取出对应的字段值=
                                WordField wordField = fieldMap.get(fieldKey);

                                // 获取字段的类型和内容
                                String fieldContent = "";
                                WordFieldTypeEnum fieldType = WordFieldTypeEnum.TEXT;
                                if (Objects.nonNull(wordField)) {
                                    String content = wordField.getContent();
                                    fieldType = wordField.getFieldType();
                                    if (Objects.isNull(fieldType)) {
                                        // 如果类型为null,默认为文本类型
                                        fieldType = WordFieldTypeEnum.TEXT;
                                    }
                                    if (StringUtils.hasLength(content)) {
                                        fieldContent = content;
                                    }
                                }

                                if (WordFieldTypeEnum.IMAGE.equals(fieldType)) {
                                    // 图片则直接把标记清除,后插入图片
                                    runText = changeValue(runText, fieldKey, "");
                                    xwpfRun.setText(runText, 0);
                                    // 插入图片
                                    insertImage(document, xwpfRun, wordField);
                                } else if (WordFieldTypeEnum.LIST.equals(fieldType)) {
                                    // 表格列表 额外处理
                                } else {
                                    // 执行替换文本
                                    runText = changeValue(runText, fieldKey, fieldContent);
                                    // 修改后的值写回
                                    xwpfRun.setText(runText, 0);
                                }

                            }
                        }


                    }
                }
            }
        }

        // 填充添加表格行
        document = insertWordTemplate(document, fieldMap);

        return document;
    }

    /**
     * 填充插入表格行
     *
     * @param document
     * @param fieldMap
     * @return
     */
    public static XWPFDocument insertWordTemplate(XWPFDocument document, Map<String, WordField> fieldMap) {


        // 遍历所有表格
        // 判断表格是否包含特定的符号
        // 如果有符号则进行处理
        List<XWPFTable> tables = document.getTables();
        boolean needInsert = false;
        String fieldKey = "";
        for (XWPFTable table : tables) {
            needInsert = false;
            fieldKey = "";
            List<XWPFTableRow> rows = table.getRows();
            tableEach:
            for (XWPFTableRow row : rows) {
                List<XWPFTableCell> tableCells = row.getTableCells();
                for (XWPFTableCell tableCell : tableCells) {
                    List<XWPFParagraph> paragraphs = tableCell.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs) {
                        String paragraphText = paragraph.getText();
                        if (checkTable(paragraphText)) {
                            List<XWPFRun> runList = paragraph.getRuns();
                            for (XWPFRun xwpfRun : runList) {
                                String runText = xwpfRun.toString();
                                if (checkTable(runText)) {

                                    // 设置标识
                                    needInsert = true;
                                    // 设置fieldKey
                                    fieldKey = getTableKey(runText);

                                    // 清除标识
                                    // 图片则直接把标记清除,后插入图片
                                    runText = changeTableValue(runText, fieldKey, "");
                                    xwpfRun.setText(runText, 0);

                                    // 跳出循环 tableEach
                                    break tableEach;
                                }
                            }
                        }
                    }
                }
            }

            if (needInsert) {
                WordField wordField = fieldMap.get(fieldKey);
                if (Objects.nonNull(wordField)) {
                    insertTable(table, wordField.getTableRowList());
                }
            }

        }

        return document;

    }

    /**
     * 获取表格中的段落信息列表
     *
     * @param document
     * @return
     */
    public static List<XWPFParagraph> getParagraphListFromTable(XWPFDocument document) {

        List<XWPFParagraph> paragraphList = new ArrayList<>();

        List<XWPFTable> tables = document.getTables();
        for (XWPFTable table : tables) {
            List<XWPFTableRow> rows = table.getRows();
            for (XWPFTableRow row : rows) {
                List<XWPFTableCell> tableCells = row.getTableCells();
                for (XWPFTableCell tableCell : tableCells) {
                    List<XWPFParagraph> paragraphs = tableCell.getParagraphs();
                    paragraphList.addAll(paragraphs);
                }
            }
        }
        return paragraphList;
    }

    /**
     * 判断文本中时候包含${{}}
     *
     * @param text 文本
     * @return 包含返回true, 不包含返回false
     */
    public static boolean checkText(String text) {
        boolean check = false;
        if (Objects.isNull(text)) {
            return false;
        }
        Matcher matcher = PATTERN_TEXT.matcher(text);
        if (matcher.find()) {
            check = true;
        }
        return check;
    }

    /**
     * 检测符号
     *
     * @param text
     * @return
     */
    public static boolean checkTextFlag(String text) {
        boolean check = false;
        if (Objects.isNull(text)) {
            return false;
        }
        if (text.indexOf(STRING_FLAG) != -1) {
            check = true;
        }
        return check;
    }


    /**
     * 判断文本中时候包含${{}}
     *
     * @param text 文本
     * @return 包含返回true, 不包含返回false
     */
    public static boolean checkTable(String text) {
        boolean check = false;
        if (Objects.isNull(text)) {
            return false;
        }
        Matcher matcher = PATTERN_TABLE.matcher(text);
        if (matcher.find()) {
            check = true;
        }
        return check;
    }

    /**
     * 检测符号
     *
     * @param text
     * @return
     */
    public static boolean checkTableFlag(String text) {
        boolean check = false;
        if (Objects.isNull(text)) {
            return false;
        }
        if (text.indexOf(TABLE_FLAG) != -1) {
            check = true;
        }
        return check;
    }

    /**
     * 获取字符串中的 fieldKey
     *
     * @param text
     * @return
     */
    public static String getFieldKey(String text) {

        Matcher matcher = PATTERN_TEXT.matcher(text);
        int i = 1;
        if (matcher.find()) {
            return matcher.group(1);
        }
        return "";

    }

    /**
     * 获取字符串中的 fieldKey
     *
     * @param text
     * @return
     */
    public static String getTableKey(String text) {

        Matcher matcher = PATTERN_TABLE.matcher(text);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return "";

    }

    /**
     * 获取字符串中的 fieldKey
     *
     * @param text
     * @return
     */
    public static List<String> getFieldKeyList(String text) {

        Matcher matcher = PATTERN_TEXT.matcher(text);
        List<String> list = new ArrayList<>();
        int i = 1;
        while (matcher.find()) {
            list.add(matcher.group(i));
        }
        return list;

    }

    /**
     * 替换值, String 传的值,
     * 返回记得写回去
     *
     * @param text  模板需要替换的文本
     * @param key   需要替换的field key
     * @param value field key 对应的 value
     * @return 模板需要替换区域信息集合对应值
     */
    public static String changeValue(String text, String key, String value) {

        if (Objects.isNull(text)) {
            return "";
        }
        if (checkText(text)) {
            // 匹配模板 进行替换 格式${{key}}
            String keyText = "${{" + key + "}}";
            if (text.indexOf(keyText) != -1) {
                text = text.replace(keyText, value);
            }
        }
        return text;
    }

    /**
     * 替换值, String 传的值,
     * 返回记得写回去
     *
     * @param text  模板需要替换的文本
     * @param key   需要替换的field key
     * @param value field key 对应的 value
     * @return 模板需要替换区域信息集合对应值
     */
    public static String changeTableValue(String text, String key, String value) {

        if (Objects.isNull(text)) {
            return "";
        }
        if (checkTable(text)) {
            // 匹配模板 进行替换 格式${{key}}
            String keyText = "#{{" + key + "}}";
            if (text.indexOf(keyText) != -1) {
                text = text.replace(keyText, value);
            }
        }
        return text;
    }


    /**
     * 给插入图片信息, 目前默认 png图片,
     * 可以继续优化
     *
     * @param document
     * @param xwpfRun
     * @param wordField
     */
    public static void insertImage(XWPFDocument document, XWPFRun xwpfRun, WordField wordField) throws IOException, InvalidFormatException {

        if (Objects.isNull(document) || Objects.isNull(xwpfRun) || Objects.isNull(wordField)) {
            return;
        }

        // 先尝试根据Base64的方式加载
        String content = wordField.getContent();
        byte[] imageBytes = new byte[0];
        if (StringUtils.hasLength(content)) {
            imageBytes = Base64.getDecoder().decode(content);
        } else {
            String imageUrl = wordField.getImageUrl();
            ByteArrayOutputStream imageOutStream = new ByteArrayOutputStream();
            HttpUtil.download(imageUrl, imageOutStream, false);
            imageBytes = imageOutStream.toByteArray();
            imageOutStream.close();
        }

        String picId = document.addPictureData(imageBytes, XWPFDocument.PICTURE_TYPE_PNG);
        addPictureToRun(xwpfRun, picId, XWPFDocument.PICTURE_TYPE_PNG, wordField.getImageWidth(), wordField.getImageHeight());
    }

    /**
     * 添加图片到run
     *
     * @param run         文本行信息
     * @param blipId      生成的 PictureData id  document.addPictureData
     * @param imageTypeId 图片类型id org.apache.poi.xwpf.usermodel.Document
     * @param width       图片宽
     * @param height      图片高
     */
    public static void addPictureToRun(XWPFRun run, String blipId, int imageTypeId, int width, int height) {
        final int EMU = 9525;
        width *= EMU;
        height *= EMU;

        CTInline inline = run.getCTR().addNewDrawing().addNewInline();

        String picXml = "" +
                "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">" +
                "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "         <pic:nvPicPr>" +
                "            <pic:cNvPr id=\"" + imageTypeId + "\" name=\"Generated\"/>" +
                "            <pic:cNvPicPr/>" +
                "         </pic:nvPicPr>" +
                "         <pic:blipFill>" +
                "            <a:blip r:embed=\"" + blipId + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>" +
                "            <a:stretch>" +
                "               <a:fillRect/>" +
                "            </a:stretch>" +
                "         </pic:blipFill>" +
                "         <pic:spPr>" +
                "            <a:xfrm>" +
                "               <a:off x=\"0\" y=\"0\"/>" +
                "               <a:ext cx=\"" + width + "\" cy=\"" + height + "\"/>" +
                "            </a:xfrm>" +
                "            <a:prstGeom prst=\"rect\">" +
                "               <a:avLst/>" +
                "            </a:prstGeom>" +
                "         </pic:spPr>" +
                "      </pic:pic>" +
                "   </a:graphicData>" +
                "</a:graphic>";

        //CTGraphicalObjectData graphicData = inline.addNewGraphic().addNewGraphicData();
        XmlToken xmlToken = null;
        try {
            xmlToken = XmlToken.Factory.parse(picXml);
        } catch (XmlException xe) {
            xe.printStackTrace();
        }
        inline.set(xmlToken);
        //graphicData.set(xmlToken);

        inline.setDistT(0);
        inline.setDistB(0);
        inline.setDistL(0);
        inline.setDistR(0);

        CTPositiveSize2D extent = inline.addNewExtent();
        extent.setCx(width);
        extent.setCy(height);

        CTNonVisualDrawingProps docPr = inline.addNewDocPr();
        docPr.setId(imageTypeId);
        docPr.setName("Picture " + imageTypeId);
        docPr.setDescr("图片" + imageTypeId);
    }


    /**
     * 为表格插入数据，行数不够添加新行
     *
     * @param table     需要插入数据的表格
     * @param tableList 插入数据集合
     */
    public static void insertTable(XWPFTable table, List<List<String>> tableList) {

        if (CollectionUtils.isEmpty(tableList)) {
            return;
        }
        int rowLength = 0;
        int dataListLength = tableList.size();

        List<XWPFTableRow> rows = table.getRows();
        if (!CollectionUtils.isEmpty(rows)) {
            rowLength = rows.size();
        }

        //创建行,根据需要插入的数据添加新行，不处理表头
        int newRowLength = 0;
        if (dataListLength > rowLength) {
            newRowLength = dataListLength - rowLength;
        }

        for (int i = 0; i <= newRowLength; i++) {
            XWPFTableRow row = table.createRow();
        }

        XWPFTableRow titleRow = table.getRow(0);
        int height = titleRow.getHeight();

        //遍历表格插入数据
        for (int i = 1; i < rows.size(); i++) {
            XWPFTableRow newRow = table.getRow(i);
            newRow.setHeight(height);

            List<XWPFTableCell> cells = newRow.getTableCells();

            // 行数据 // 列数据
            List<String> columnList = tableList.get(i - 1);
            if (CollectionUtils.isEmpty(columnList)) {
                continue;
            }

            // 遍历列数据放进去
            int listSize = columnList.size();
            for (int j = 0; j < cells.size(); j++) {
                XWPFTableCell cell = cells.get(j);
                // cell 居中
                cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                List<XWPFParagraph> paragraphs = cell.getParagraphs();
                if (!CollectionUtils.isEmpty(paragraphs)) {
                    XWPFParagraph par = paragraphs.get(0);

                    // 设置居中
                    par.setAlignment(ParagraphAlignment.CENTER);
                    par.setVerticalAlignment(TextAlignment.CENTER);

                    //XWPFRun   设置格式
                    XWPFRun run = par.createRun();
                    run.setFontFamily("宋体");
                    if (listSize > j) {
                        String text = columnList.get(j);
                        run.setText(text);
                    }
                }
            }
        }

    }


    /**
     * 检查是否合格
     *
     * @param filePath
     */
    public static void checkPassed(String filePath) throws IOException {
        //解析docx模板并获取document对象
        XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(filePath));
        // 所有的段落信息
        List<XWPFParagraph> paragraphTextList = new ArrayList<>();
        List<XWPFParagraph> paragraphList = document.getParagraphs();
        List<XWPFParagraph> paragraphListFromTable = getParagraphListFromTable(document);

        // 将文章段落和表格的段落全部加在一起
        if (!CollectionUtils.isEmpty(paragraphList)) {
            paragraphTextList.addAll(paragraphList);
        }
        if (!CollectionUtils.isEmpty(paragraphListFromTable)) {
            paragraphTextList.addAll(paragraphListFromTable);
        }


        //获取所有的段落
        for (XWPFParagraph xwpfParagraph : paragraphTextList) {

            // 遍历检查 $
            String paragraphText = xwpfParagraph.getText();
            if (checkTextFlag(paragraphText)) {
                System.out.println("/$ " + xwpfParagraph.getText());
                List<XWPFRun> runList = xwpfParagraph.getRuns();
                for (XWPFRun xwpfRun : runList) {
                    String runText = xwpfRun.toString();
                    if (checkTextFlag(runText)) {
                        System.out.println("-$ " + runText);
                    }
                }
            }

            // 遍历检查 #
            if (checkTableFlag(paragraphText)) {
                System.out.println("/# " + xwpfParagraph.getText());
                List<XWPFRun> runList = xwpfParagraph.getRuns();
                for (XWPFRun xwpfRun : runList) {
                    String runText = xwpfRun.toString();
                    if (checkTableFlag(runText)) {
                        System.out.println("-# " + runText);
                    }
                }


            }
        }
    }

    /**
     * 导出word文件到 response 返回给前端
     *
     * @param response
     * @param fileName
     * @param xwpfDocument
     * @throws IOException
     */
    public static void exportWord(HttpServletResponse response, String fileName, XWPFDocument xwpfDocument) throws IOException {
        fileName = URLEncoder.encode(fileName, "UTF-8");
        fileName = fileName + ".docx";
        response.setContentType("application/ms-word;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        ServletOutputStream outputStream = response.getOutputStream();
        xwpfDocument.write(outputStream);
        outputStream.close();
        xwpfDocument.close();

    }


    public static void main(String[] args) throws IOException, InvalidFormatException {
//        String a = "${{啊}}233,${{啊4}},4444${{23啊}}asdf${{啊3}}发斯蒂芬${{啊32}}$发发发{{2234啊}}发到${{53啊}}${{df啊}}${{啊d}}${{啊ae}}哒哒哒哒哒哒${{啊ffffff}}";
//        System.out.println(a);
//        List<String> fieldKeyList = getFieldKeyList(a);
//        for (String s : fieldKeyList) {
//            System.out.println(s);
//            String a1 = changeValue(a, s, " 测试 ");
//            System.out.println(a1);
////            a = a1;
//            System.out.println(a);
//        }


        String filePath = "D:\\tmp\\demo_temp\\demo_template1.docx";
        String outFilePath = "D:\\tmp\\demo_temp\\demo_out35.docx";

        checkPassed("D:\\tmp\\demo_temp\\template1.docx");
        checkPassed(filePath);

        Map<String, WordField> wordFieldMap = new HashMap<>(9);

        WordField no = new WordField();
        WordField typeIdentification = new WordField();
        WordField manufacturer = new WordField();
        WordField client = new WordField();
        WordField testType = new WordField();
        WordField testDate = new WordField();
        WordField img = new WordField();
        WordField img2 = new WordField();
        WordField add1 = new WordField();


        List<List<String>> tableRowList = new ArrayList<>();

        Arrays.asList(new String[]{"1", "#3", "#3", "#12", "3233"});
        Arrays.asList(new String[]{"3", "d#3", "#fa3", "#12", "3f"});
        Arrays.asList(new String[]{"4", "#3", "#f3", "#1f2", "af3"});
        Arrays.asList(new String[]{"5", "#fa3", "#fa3", "#12", "33"});


        tableRowList.add(Arrays.asList(new String[]{"1", "#3", "#3", "#12", "3233"}));
        tableRowList.add(Arrays.asList(new String[]{"3", "d#3", "#fa3", "#12", "3f"}));
        tableRowList.add(Arrays.asList(new String[]{"4", "#3", "#f3", "#1f2", "af3"}));
        tableRowList.add(Arrays.asList(new String[]{"5", "#fa3", "#fa3", "#12", "33"}));
        add1.setTableRowList(tableRowList);


        no.setContent("001");
        no.setFieldType(WordFieldTypeEnum.TEXT);

        typeIdentification.setContent("00333331");
        typeIdentification.setFieldType(WordFieldTypeEnum.TEXT);

        manufacturer.setContent("00434441");
        manufacturer.setFieldType(WordFieldTypeEnum.TEXT);

        client.setContent("4324234");
        client.setFieldType(WordFieldTypeEnum.TEXT);

        testType.setContent("testType3232");
        testType.setFieldType(WordFieldTypeEnum.TEXT);

        testDate.setContent("243444");
        testDate.setFieldType(WordFieldTypeEnum.TEXT);
        img.setContent("/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIs" +
                "IxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj" +
                "IyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAA8AKADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QA" +
                "tRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk" +
                "6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx" +
                "8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECB" +
                "AQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZ" +
                "HSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tP" +
                "U1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtrW1ga1hZoIySikkoOeKsCztv+feL/vgU2z/484P+ua/yqyK" +
                "iMY8q0IjGPKtCIWdr/wA+0P8A3wKeLK1/59of+/YqUVBeX9tp1q9zdzJDDGMs7HgVSpqTslqPlj2JBZWn/PrD/wB+xThY2n/PrB/" +
                "37Fcpb/E7wxPc+T9rkjBOBI8RCn/PvXXW1zDdQrLDIskbDKspyCK3r4Krh7e2puN+6sJKD2AWFn/z6wf9+xThYWf/AD6Qf9+xUu4A" +
                "VgaV400zV9cutJtVuDNb53SMg2HHoc/0qIYeVSMpQjdR1fkNqK6G6NPsv+fS3/79j/CnDTrL/nzt/wDv0v8AhVa91zStMdUv9RtL" +
                "V2XcqzzKhI9QCea5/UPij4WsMgX7XLj+G2jLfrwP1rSjga1b+FTb9FcT5FvY6wadY/8APnb/APfpf8KcNNsf+fK3/wC/S/4Vi+Ff" +
                "GOn+LbeeaxiuI1gcIwnVQSSM8YJrpBWVXDyozdOpGzW6GlFq6RXGmWH/AD5W3/fpf8KeNMsP+fG2/wC/S/4VYFJNPHbQPNKwWON" +
                "SzMewAyaz5I9g5Y9iIaXp/wDz423/AH5X/CnjStP/AOfC1/78r/hWNB468Lz/AHNcsR7vKFH5nitey1jTr84s762uP+uUob+Rra" +
                "eFqU/jg16oSUGSDStO/wCfC1/78r/hThpOnf8AQPtf+/K/4VaHNPFY8sew+WPYqjSdN/6B9p/35X/Cq2p6Xp8ekXrpY2qusDlW" +
                "EKgg7TyOK1hVXVv+QLf/APXvJ/6CaUox5XoKUY8r0OSs/wDjzg/65r/KrIqvZ/8AHnB/1zX+VWRTj8KHH4UKeBXmXxXnmk0iGN" +
                "CfLWbMgHfjj9a9NIytcX4u0z7VburLuUjBFduBxP1XEwr2vyu4SjzJo8v8P2em39i8Vxbh5Q3LgkEelX9N1rVfAepgRyNc6ZIe" +
                "Y2PB+no386xQlz4a1RZwpkgJwQf4l9D712dzb2etaSJYj5lvKvbqp/oRX1WNxbpVfbzftcLV6PW3p2a6bfejCMbq20kejW3iC0" +
                "1bSEvrKXfE4/EH0Poa8w8D3Z07xvqdvKcSSlsE9/mz/KsHRdWuvCesPbTMWs5TiRexHZh7j/PrV/xFG9hqltrtlztYF8dD/wDrr" +
                "CngVh6s8LGV6dePuS81qk/y+4pyulLqjd+KcBv7W1vFGZLbKt7ocfyI/U1wFgNGSBZL3z3kzho1OB/n8a9ZuEh8Q6JFdwfMkq" +
                "Zx1x6g1xMHhBYLx2eIyLn5VYZArDAZtGhhZYTEylHlenLo/OPlrr/WpKneXMjsvhzqfh+OSS20tlgmmILxO7ZYj03H37V6vG4" +
                "2jJr591DwpE8YmsQbS8T5lKkhWP8AQ+4rQ0vxouuaXL4Y8VoWkb5EuDw24dM+jA9D37+/PWwNPGJ4rDTlJL4lLWaXf+8ilJx9" +
                "1o9h1DxPomkg/btUtICP4WlG7/vnqa5m++JvhK5jeBNVV94KkGGQAg+5XFeWS+F9C0k51HUZJD1C5Eefw5P5VER4MkHlquw/" +
                "398v9eKull+Acbx9rU84w0/ETnPyRbj8I6FMheC9muIiTiSJ1/Loawb+Cfwtq8Fxpt3ICDvRujAg9D613PhTQtPiuXl07VRN" +
                "byL+8t2ZX57EEYwR9K5v4g6fJb38MiKTEQV47GvTy7Mq08xWHqVXOnK+klbps13/AAZE4JQulqfQHhTXV1/QbO/xtaaIMy+" +
                "jd/1zXQivNfhZPu8NWsex02LtKupHP416UvSvkcVCNOvOEdk2l950Rd0h4qrq3/IEv/8Ar2k/9BNWxVXV/wDkCX//AF7Sf+gmu" +
                "aXwsUvhZyVn/wAeUH/XNf5VZFV7L/jyg/65r/KrIoj8KCPwocBVW8tFuIipGatinYzVFHmmveHkZZEeMNG/BFcIn9peFLqRoE" +
                "NxYSH5lPT8fQ+9e+XdilxGQRXI6j4dfcTGODXo4HMZYZSpyjz05bxe3quz8yJQ5tep49qd5Jrl4nkWrIV4Azk128OmO/htLW4" +
                "+Y+TsPetm28LSNMCUwAfSt+40XZp7R4IyuMjqK3xmbe2p06NGHJCDutW3f1Yo07Nt63ON+FF4zre6ZKdyRsHT2zwf5V6Dquj" +
                "pLYTLDKYJmU+XKo+63Y+49q5TwZ4Z/sTULiVZXkMp/iXGBXos9sZrfHfFZZriaVfGyr0NnZ/Oyvp6jgmo2Z4Xda14p00FdU0" +
                "9JlH/AC0CgfqvH6VyGpXx1K+a48rYzYyBzXumqaDPIW255rmY/BsjXwlMQznrt5r08Fn9DD1HV+rpSta8W0vu1REqTatcrx" +
                "6Imu6BZf2jG5nRQdwOGz9ffjNVJPBunbdos3H+0JGz/OvWNH0IR26q69q0zoMDD7g/KvHWY4qF1SqOKu3ZNpK5pyR6o8Gk8" +
                "BW8j/ubyaH2dA/+Fb2m+F5tP01rVr17iLJKHZtMeeuOT9a9Tbw1CWyFFStoMYhKhRV4jNsZiaXsa0+aO+qX52uJU4p3SPF" +
                "PC+reJfDfi5PtC6jeaeJPKm+R3TYT98dgRwfzFfRltIJIwR3riofD8kV3vUHGa7GxiMcQBqMdjFi5RlyKLSs7dfOw4x5ep" +
                "dFVdX/5Al//ANe0n/oJq2Kq6v8A8gS//wCvaT/0E158vhYS+FnJWX/Hlb/9c1/lVkVzMWtXMUSRqkRCKFGQe341J/b91/z" +
                "zh/75P+NZRrRsjONWNkdKKcK5n/hIbv8A55wf98n/ABpf+Eiu/wDnnB/3yf8AGq9tEftonUAUhhVuoFcz/wAJJef88oP+" +
                "+T/jS/8ACS3n/PKD/vk/40e2iHtonTJboDwop0lusi4IrmP+Envf+eVv/wB8t/jS/wDCUXv/ADyt/wDvlv8AGj20Q9tE6" +
                "GDT44n3AVfVRjFch/wlV8P+WVv/AN8t/jS/8JXff88rb/vlv8aPbRD20TrjAjdQKRbKIHO0Vyf/AAlt/wD88bb/AL5b/G" +
                "l/4S/UP+eNt/3y3/xVHtoh7aJ2iRhRgCpQK4f/AITDUP8Anja/98t/8VS/8JlqP/PG1/75b/4qj20Q9tE7oCnbQa4T/hM9" +
                "R/542v8A3w3/AMVS/wDCa6l/zwtP++G/+Ko9tEPbRO6ES5zipVAFcD/wm2pf88LT/vhv/iqX/hONT/54Wn/fDf8AxVHto" +
                "h7aJ6CKq6v/AMgPUP8Ar2k/9BNcV/wnOp/88LT/AL4b/wCKqO58Z6jdWs1u8NqElRkYqrZAIxx81TKtGzFKrGzP/9k=");
        img.setFieldType(WordFieldTypeEnum.IMAGE);
        img.setImageWidth(100);
        img.setImageHeight(40);


        img2.setImageUrl("http://lamer.t.haikevr.com/assets/bg_picture@2x.b9ce2442.png");
        img2.setFieldType(WordFieldTypeEnum.IMAGE);
        img2.setImageWidth(300);
        img2.setImageHeight(300);


        wordFieldMap.put("no", no);
        wordFieldMap.put("typeIdentification", typeIdentification);
        wordFieldMap.put("manufacturer", manufacturer);
        wordFieldMap.put("client", client);
        wordFieldMap.put("testType", testType);
        wordFieldMap.put("testDate", testDate);
        wordFieldMap.put("img", img);
        wordFieldMap.put("img2", img2);
        wordFieldMap.put("add1", add1);

        XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(filePath));
        XWPFDocument xwpfDocument = fillWordTemplate(document, wordFieldMap);
//        XWPFDocument xwpfDocument2 = insertWordTemplate(xwpfDocument, wordFieldMap);

        File file = new File(outFilePath);
        FileOutputStream stream = new FileOutputStream(file);
        xwpfDocument.write(stream);
        stream.close();
    }

}
